home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / shape library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  13.2 KB  |  438 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     gxShape library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1991 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6.     #include <Memory.h>
  7. #include "graphics libraries.h"
  8.  
  9. gxShape NewPolygon(const gxPolygon *polyData)
  10. {
  11.     gxShape sh;
  12.  
  13.     NilParamReturnNil(polyData);
  14.     sh = GXNewShape(gxPolygonType);
  15.     SetPolygon(sh, 0, polyData);
  16.     return sh;
  17. }
  18.  
  19. gxShape NewPath(const gxPath *pathData)
  20. {
  21.     gxShape sh;
  22.  
  23.     NilParamReturnNil(pathData);
  24.     sh = GXNewShape(gxPathType);
  25.     SetPath(sh, 0, pathData);
  26.     return sh;
  27. }
  28.  
  29. gxPath *GetPath(gxShape source, long contour, register gxPath *pathData)
  30. {
  31.     NilShapeReturnNil(source);
  32.     NilParamReturnNil(pathData);
  33.     {   register gxPaths *tempData;
  34.         long index = GXGetShapeIndex(source, contour, 1);
  35.         long points = GXCountShapePoints(source, contour);
  36.         long size = GXGetPathParts(source, index, points, nil);
  37.         
  38.         tempData = (gxPaths *) NewPtr(size);
  39.         NilParamReturnNil(tempData);
  40.         GXGetPathParts(source, index, points, tempData);
  41.         BlockMove(&tempData->contour[0], pathData, size - sizeof(long));
  42.         DisposePtr((Ptr) tempData);
  43.         return pathData;
  44.     }
  45. }
  46.  
  47. gxPolygon *GetPolygon(gxShape source, long contour, register gxPolygon *polygonData)
  48. {
  49.     NilShapeReturnNil(source);
  50.     NilParamReturnNil(polygonData);
  51.     {   register gxPolygons *tempData;
  52.         long index = GXGetShapeIndex(source, contour, 1);
  53.         long points = GXCountShapePoints(source, contour);
  54.         long size = GXGetPolygonParts(source, index, points, nil);
  55.     
  56.         tempData = (gxPolygons *) NewPtr(size);
  57.         NilParamReturnNil(tempData);
  58.         GXGetPolygonParts(source, index, points, tempData);
  59.         BlockMove(&tempData->contour[0], polygonData, size - sizeof(long));
  60.         DisposePtr((Ptr) tempData);
  61.         return polygonData;
  62.     }
  63. }
  64.  
  65. void SetPolygon(gxShape source, long contour, register const gxPolygon *polygonData)
  66. {
  67.     NilShapeReturn(source);
  68.     NilParamReturn(polygonData);
  69.     {   long size = (long) &((gxPolygons *) 0)->contour[0].vector[polygonData->vectors];
  70.         register gxPolygons *tempData;
  71.         
  72.         tempData = (gxPolygons *) NewPtr(size);
  73.         NilParamReturn(tempData);
  74.         BlockMove(polygonData, &tempData->contour[0], size - sizeof(long));
  75.         tempData->contours = 1;
  76.         if( contour )
  77.             GXSetPolygonParts(source, GXGetShapeIndex(source, contour, 1), GXCountShapePoints(source, contour), tempData, 0);
  78.         else
  79.             GXSetPolygons(source, tempData);
  80.         DisposePtr((Ptr) tempData);
  81.     }
  82. }
  83.  
  84. void SetPath(gxShape source, long contour, register const gxPath *pathData)
  85. {
  86.     NilShapeReturn(source);
  87.     NilParamReturn(pathData);
  88.     {   long size = ((long) &((gxPaths *) 0)->contour[0].vector[pathData->vectors]) + pathData->vectors / 32 * sizeof(long);
  89.         register gxPaths *tempData;
  90.     
  91.         tempData = (gxPaths *) NewPtr(size);
  92.         NilParamReturn(tempData);
  93.         BlockMove(pathData, &tempData->contour[0], size - sizeof(long));
  94.         tempData->contours = 1;
  95.         if( contour )
  96.             GXSetPathParts(source, GXGetShapeIndex(source, contour, 1), GXCountShapePoints(source, contour), tempData, 0);
  97.         else
  98.             GXSetPaths(source, tempData);
  99.         DisposePtr((Ptr) tempData);
  100.     }
  101. }
  102.  
  103. void DrawPolygon(const gxPolygon *polyData, gxShapeFill fill)
  104. {
  105.     gxShape sh;
  106.  
  107.     NilParamReturn(polyData);
  108.     sh = NewPolygon(polyData);
  109.     GXSetShapeFill(sh, fill);
  110.     GXDrawShape(sh);
  111.     GXDisposeShape(sh);
  112. }
  113.  
  114.  
  115. void DrawPath(const gxPath *pathData, gxShapeFill fill)
  116. {
  117.     gxShape sh;
  118.  
  119.     NilParamReturn(pathData);
  120.     sh = NewPath(pathData);
  121.     GXSetShapeFill(sh, fill);
  122.     GXDrawShape(sh);
  123.     GXDisposeShape(sh);
  124. }
  125.  
  126. void SetShapeIndexPoint(gxShape source, long index, const gxPoint *data)
  127. {
  128.     GXSetShapePoints(source, index, 1, data);
  129. }
  130.  
  131. gxPoint *GetShapeIndexPoint(gxShape source, long index, gxPoint *data)
  132. {
  133.     GXGetShapePoints(source, index, 1, data);
  134.     return data;
  135. }
  136.  
  137. void SetShapeIndexControl(gxShape source, long index, long control)
  138. {
  139.     NilShapeReturn(source);
  140.     if( GXGetShapeType(source) == gxPathType ) 
  141.     {   long pathData[6];
  142.     
  143.         GXGetPathParts(source, index, 1, (gxPaths *)pathData);
  144.         if( control )
  145.             pathData[2] = 0x80000000;
  146.         else
  147.             pathData[2] = 0x00000000;
  148.         GXSetPathParts(source, index, 1, (gxPaths *)pathData, 0);
  149.     } else
  150.         GXPostGraphicsWarning(graphic_type_does_not_contain_control_bits);
  151. }
  152.  
  153. long GetShapeIndexControl(gxShape source, long index, long *control)
  154. {
  155.     NilShapeReturnNil(source);
  156.     IfErrorReturnNil(index < 1 || index > GXCountShapePoints(source, 0), index_out_of_range);
  157.     {   gxShapeType theType = GXGetShapeType(source);
  158.         long result = 0;
  159.     
  160.         switch( theType )
  161.         {
  162.             case gxPathType:
  163.             {
  164.                 long pathData[6];
  165.                 GXGetPathParts(source, index, 1, (gxPaths *)pathData);
  166.                 if( pathData[2] )
  167.                     result = true;
  168.                 break;
  169.             }
  170.             case gxGlyphType:
  171.             {
  172.                 long bits;
  173.                 GXGetGlyphPositions(source, index, 1, &bits, nil);
  174.                 if( bits )
  175.                     result = true;
  176.                 break;
  177.             }
  178.             case gxCurveType:
  179.                 if( index == 2 )
  180.                     result = 1;
  181.         }
  182.     
  183.         if( control )
  184.             *control = result;
  185.         return result;
  186.     }
  187. }
  188.  
  189. void InsertShape(gxShape source, long index, gxShape toAdd)
  190. {
  191.     GXSetShapeParts(source, index, 0, toAdd, gxBreakLeftEdit + gxBreakRightEdit + gxRemoveDuplicatePointsEdit);
  192. }
  193.  
  194. gxShape ExtractShape(gxShape source, long firstPoint, long numPoints)
  195. {
  196.     gxShape newShape;
  197.  
  198.     newShape = GXGetShapeParts(source, firstPoint, numPoints, nil);
  199.     if( newShape )
  200.         GXSetShapeParts(source, firstPoint, numPoints, nil, gxRemoveDuplicatePointsEdit);
  201.     return newShape;
  202. }
  203.  
  204. void AddToShape(gxShape dest, gxShape add)
  205. {
  206.     GXSetShapeParts(dest, 0, 0, add, gxBreakLeftEdit);
  207. }
  208.  
  209. void ExtendShape(gxShape dest, gxShape add)
  210. {
  211.     GXSetShapeParts(dest, 0, 0, add, 0);
  212. }
  213.  
  214. #ifdef debugging
  215. gxShape NewShape2(gxShapeType typeID, long arg1, long arg2)
  216. {
  217.     IfWarningReturnNil(typeID != gxPointType, point_expected);
  218.     return NewShapeMany(typeID, arg1, arg2);
  219. }
  220.  
  221. gxShape NewShape4(gxShapeType typeID, long arg1, long arg2, long arg3, long arg4)
  222. {
  223.     IfWarningReturnNil(typeID != gxLineType && typeID != gxRectangleType, line_or_rectangle_expected);
  224.     return NewShapeMany(typeID, arg1, arg2, arg3, arg4);
  225. }
  226.  
  227. gxShape NewShape6(gxShapeType typeID, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
  228. {
  229.     IfWarningReturnNil(typeID != gxCurveType, curve_expected);
  230.     return NewShapeMany(typeID, arg1, arg2, arg3, arg4, arg5, arg6);
  231. }
  232.  
  233. void SetShape2(register gxShape dest, long arg1, long arg2)
  234. {
  235.     IfWarningReturn(GXGetShapeType(dest) != gxPointType, point_expected);
  236.     SetShapeMany(dest, arg1, arg2);
  237. }
  238.  
  239. void SetShape4(register gxShape dest, long arg1, long arg2, long arg3, long arg4)
  240. {
  241.     register gxShapeType typeID;
  242.  
  243.     NilShapeReturn(dest);
  244.     typeID = GXGetShapeType(dest);
  245.     IfWarningReturn(typeID != gxLineType && typeID != gxRectangleType, line_or_rectangle_expected);
  246.     SetShapeMany(dest, arg1, arg2, arg3, arg4);
  247. }
  248.  
  249. void SetShape6(register gxShape dest, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
  250. {
  251.     register gxShapeType typeID;
  252.  
  253.     NilShapeReturn(dest);
  254.     typeID = GXGetShapeType(dest);
  255.     IfWarningReturn(typeID != gxCurveType, curve_expected);
  256.     SetShapeMany(dest, arg1, arg2, arg3, arg4, arg5, arg6);
  257. }
  258. #endif
  259.  
  260. gxShape NewShapeMany(gxShapeType type, Fixed arg1, ...)
  261. {
  262.     return GXNewShapeVector(type, &arg1);
  263. }
  264.  
  265. void SetShapeMany(gxShape sourceShape, Fixed arg1, ...)
  266. {
  267.     NilShapeReturn(sourceShape);
  268.     GXSetShapeVector(sourceShape, &arg1);
  269. }
  270.  
  271. void CenterShape(gxShape target, gxRectangle *container)
  272. {
  273.     gxRectangle shapeBounds;
  274.     
  275.     NilShapeReturn(target);
  276.     NilParamReturn(container);
  277.     GXGetShapeBounds(target, 0, &shapeBounds);
  278.     GXMoveShape(target,   ((container->left + container->right) - (shapeBounds.left + shapeBounds.right))/2,
  279.                     ((container->top + container->bottom) - (shapeBounds.top + shapeBounds.bottom))/2);
  280. }
  281.  
  282. void MoveShapeCenterTo(gxShape target, Fixed x, Fixed y)
  283. {
  284.     gxPoint centerPt;
  285.    gxShapeAttribute oldAttributes = 0;
  286.    
  287.     NilShapeReturn(target);
  288.     GXGetShapeCenter(target, 0, ¢erPt);
  289.     if (GXGetShapeType(target) == gxLayoutType && (oldAttributes = GXGetShapeAttributes(target)) & gxMapTransformShape)
  290.         GXSetShapeAttributes(target, oldAttributes & ~gxMapTransformShape);
  291.     GXMoveShape(target, x - centerPt.x, y - centerPt.y);
  292.     if (oldAttributes & gxMapTransformShape)
  293.         GXSetShapeAttributes(target, oldAttributes);
  294. }
  295.  
  296. void RotateShapeAboutCenter(gxShape target, Fixed degrees)
  297. {
  298.     gxPoint centerPt;
  299.  
  300.     NilShapeReturn(target);
  301.     GXGetShapeCenter(target, 0, ¢erPt);
  302.     GXRotateShape(target, degrees, centerPt.x, centerPt.y);
  303. }
  304.  
  305. void SkewShapeAboutCenter(gxShape target, Fixed xSkew, Fixed ySkew)
  306. {
  307.     gxPoint centerPt;
  308.  
  309.     NilShapeReturn(target);
  310.     GXGetShapeCenter(target, 0, ¢erPt);
  311.     GXSkewShape(target, xSkew, ySkew, centerPt.x, centerPt.y);
  312. }
  313.  
  314. void ScaleShapeAboutCenter(gxShape target, Fixed hScale, Fixed vScale)
  315. {
  316.     gxPoint centerPt;
  317.  
  318.     NilShapeReturn(target);
  319.     GXGetShapeCenter(target, 0, ¢erPt);
  320.     GXScaleShape(target, hScale, vScale, centerPt.x, centerPt.y);
  321. }
  322.  
  323. void SetShapeOpenPath(gxShape target)
  324. {
  325.     long contours, i, index;
  326.  
  327.     NilShapeReturn(target);
  328. #ifdef debugging
  329.     GXIgnoreGraphicsNotice(type_already_set);
  330. #endif
  331.     GXSetShapeType(target, gxPathType);
  332. #ifdef debugging
  333.     GXPopGraphicsNotice();
  334.     GXIgnoreGraphicsNotice(parameters_have_no_effect);
  335. #endif
  336.     GXSetShapeFill(target, gxOpenFrameFill);
  337. #ifdef debugging
  338.     GXPopGraphicsNotice();
  339. #endif
  340.  
  341.     contours = GXCountShapeContours(target);
  342.     index = 0;
  343.     for (i = 1; i <= contours; i++) {
  344.         long points = GXCountShapePoints(target,i);
  345.         if (points) {
  346.             SetShapeIndexControl(target,index += 1,false);
  347.             SetShapeIndexControl(target,index += points-1,false);
  348.         }
  349.     }
  350. }
  351.  
  352. /*******************/
  353. /* drawing operations          */
  354. /*******************/
  355. static void CommonPaint(gxShape s, commonColor c)
  356. {
  357.     NilShapeReturn(s);
  358. #ifdef debugging    
  359.     GXIgnoreGraphicsNotice(color_already_set);
  360. #endif
  361.     SetShapeCommonColor(s,c);
  362. #ifdef debugging    
  363.     GXPopGraphicsNotice();
  364. #endif
  365.     GXDrawShape(s);
  366.     GXDisposeShape(s);
  367. }
  368.  
  369.  
  370. void PaintRectangle(const gxRectangle *r, commonColor c)
  371. {
  372.     CommonPaint(GXNewRectangle(r),c);
  373. }
  374.  
  375. void PaintRectangle2(const gxPoint *pt1, const gxPoint *pt2, commonColor c)
  376. {
  377.     CommonPaint(NewShape4(gxRectangleType, pt1->x, pt1->y, pt2->x, pt2->y),c);
  378. }
  379.  
  380. void PaintRectangle4(Fixed left, Fixed top, Fixed right, Fixed bottom, commonColor c)
  381. {
  382.     CommonPaint(NewShape4(gxRectangleType, left, top, right, bottom),c);
  383. }
  384.  
  385. /*******************/
  386. /* operations on geometries */
  387. /*******************/
  388.  
  389. void GetPathsIndexPointControl(const gxPaths *pathData, long index, gxPoint **pt, long **controlPtr, long *controlMask)
  390. {
  391.     NilParamReturn(pathData);
  392.     {   register long *pathWalker = (long *) pathData;
  393.         register short contours = *pathWalker++;
  394.         register short vectors;
  395.     
  396.         while (contours && index > (vectors = *pathWalker++)) {
  397.             pathWalker += (vectors + 31 >> 5) + (vectors << 1);
  398.             contours--;
  399.             index -= vectors;
  400.             }
  401.         if (contours) {
  402.             index--;
  403.             if (controlPtr)
  404.                 *controlPtr = &pathWalker[index >> 5];
  405.              if (controlMask)
  406.                 *controlMask = 0x80000000 >> (index & 31);
  407.             pathWalker += vectors + 31 >> 5;
  408.             if (pt)
  409.                 *pt = (gxPoint *) (pathWalker + (index << 1));
  410.         } else
  411.             GXPostGraphicsWarning(index_out_of_range_in_contour);
  412.     }
  413. }
  414.  
  415. /**************************/
  416. /* Get/GXSetBitmapParts utility routines */
  417. /**************************/
  418.  
  419. gxShape GetBitmapPartsFromFixedBounds(gxShape source, const gxRectangle *bounds)
  420. {
  421.     gxLongRectangle pixelBounds;
  422.     pixelBounds.top = FixedRound(bounds->top);          /* use = ((bounds->top + 0x00007fff) >> 16) if you want to include */
  423.     pixelBounds.left = FixedRound(bounds->left);            /* pixels whose centers touch the bounding gxRectangle on the top */
  424.     pixelBounds.bottom = FixedRound(bounds->bottom);        /* (the same applies for left, as well) */
  425.     pixelBounds.right = FixedRound(bounds->right);
  426.     return (GXGetBitmapParts(source, &pixelBounds));
  427. }
  428.  
  429. void SetBitmapPartsFromFixedBounds(gxShape target, const gxRectangle *bounds, gxShape bitmapShape)
  430. {
  431.     gxLongRectangle pixelBounds;
  432.     pixelBounds.top = FixedRound(bounds->top);          /* use = ((bounds->top + 0x00007fff) >> 16) if you want to include */
  433.     pixelBounds.left = FixedRound(bounds->left);            /* pixels whose centers touch the bounding gxRectangle on the top */
  434.     pixelBounds.bottom = FixedRound(bounds->bottom);
  435.     pixelBounds.right = FixedRound(bounds->right);
  436.     GXSetBitmapParts(target, &pixelBounds, bitmapShape);
  437. }
  438.